package com.haiyou.common.util;


import com.alibaba.fastjson.JSON;
import com.haiyou.common.entity.SortedSetEntity;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.ZSetOperations;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.Set;

/**
 * 有序redis 工具类
 */
@Component
public class SortedSetRedisUtils {

    @Autowired
    private ZSetOperations<String, Object> zSetOperations;

    /**
     * 集合第一个元素
     */
    public Set<ZSetOperations.TypedTuple<Object>> rangeWithScores(String sortedSetKey) {
        return zSetOperations.rangeWithScores(sortedSetKey, 0L, 0L);
    }

    /**
     * 获取总数
     *
     * @param sortedSetKey
     * @return
     */
    public Long getCount(String sortedSetKey) {
        return zSetOperations.size(sortedSetKey);
    }

    /**
     * 新增或者更新数据
     * @param sortedSetKey
     * @param bean
     * @param score
     */
    /**
     * 新增或者更新数据
     *
     * @param sortedSetKey key（用于区分不同的排行榜）
     * @param member       排行榜对象（商品相关的排行榜统一为商品ID）
     * @param score        排行依据（权重值，最新，最热，好评 ，价钱...）
     *                     如果在key中，不存在该member，则新增，如果存在，则更新
     */
    public void addOrUpdate(String sortedSetKey, String member, double score) {
        zSetOperations.add(sortedSetKey, member, score);
    }

    /**
     * 获取排行榜指定范围的内容
     *
     * @param sortedSetKey key（用于区分不同的排行榜）
     * @param startIndex   起始值（从0开始）
     * @param endIndex     结束值
     * @return
     */
    public Set<Object> reverseRange(String sortedSetKey, Long startIndex, Long endIndex) {
        Set<Object> range = zSetOperations.reverseRange(sortedSetKey, startIndex, endIndex);
        return range;
    }

    /**
     * 获取排行榜前N的数据
     *
     * @param sortedSetKey key（用于区分不同的排行榜）
     * @param number
     * @return
     */
    public Set<Object> top(String sortedSetKey, Long number) {
        Set<Object> topRange = zSetOperations.reverseRange(sortedSetKey, 0L, number);
        return topRange;
    }

    /**
     * 获取排名
     *
     * @param sortedSetKey key（用于区分不同的排行榜）
     * @param member       排行榜对象（商品相关的排行榜统一为商品ID）
     * @return
     */
    public Long getRankNum(String sortedSetKey, String member) {
        Long rankNum = zSetOperations.reverseRank(sortedSetKey, member);
        return rankNum;
    }


    /**
     * 批量新增/更新数据
     *
     * @param sortedSetKey key（用于区分不同的排行榜）
     * @param tuples       Set<ZSetOperations.TypedTuple<String>> tuples = new HashSet<>();
     *                     long start = System.currentTimeMillis();
     *                     for (int i = 0; i < 100000; i++) {
     *                     DefaultTypedTuple<String> tuple = new DefaultTypedTuple<>("张三" + i, 1D + i);
     *                     tuples.add(tuple);
     *                     }
     */
    public Long addOrUpdateSet(String sortedSetKey, Set<ZSetOperations.TypedTuple<Object>> tuples) {
        if (null != tuples && tuples.size() > 0) {
            return zSetOperations.add(sortedSetKey, tuples);
        }
        return 0L;
    }

    /**
     * 删除数据
     *
     * @param sortedSetKey （用于区分不同的排行榜）
     * @param member       排行榜对象（商品相关的排行榜统一为商品ID）
     * @return
     */
    public Long remove(String sortedSetKey, String member) {
        return zSetOperations.remove(sortedSetKey, member);
    }

    /**
     * 查询，范围内的数据
     *
     * @param sortedSetKey key（用于区分不同的排行榜）
     * @param startIndex   起始值（从0开始）
     * @param endIndex     结束值
     * @return
     */
    public List<SortedSetEntity> getRangeData(String sortedSetKey, Long startIndex, Long endIndex) {
        Set<ZSetOperations.TypedTuple<Object>> rangeWithScores = zSetOperations.reverseRangeWithScores(sortedSetKey, startIndex, endIndex);
        String jsonString = JSON.toJSONString(rangeWithScores);
        return JSON.parseArray(jsonString, SortedSetEntity.class);
    }

}
